﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RentAWorker.DataAccess.Interfaces;
using System.Data.Objects;
using RentAWorker.DataAccess.Entities;

namespace RentAWorker.DataAccess
{
    public class RentalServiceDataAccess : IRentalServiceAccess
    {
        public RentalService GetRentalService(int rentalServiceId)
        {
            using (BigDays2009Entities db = new BigDays2009Entities())
            {
                db.RentalService.MergeOption = MergeOption.NoTracking;

                return (from rs in db.RentalService.Include("Customer").Include("Resource").Include("RentalServiceState")
                        where rs.RentalServiceID == rentalServiceId
                        select rs).First();
            }
        }

        public IEnumerable<RentalService> GetRentalServicesByCustomer(int customerId)
        {
            using (BigDays2009Entities db = new BigDays2009Entities())
            {
                db.RentalService.MergeOption = MergeOption.NoTracking;

                return (from rs in db.RentalService.Include("Customer").Include("Resource").Include("RentalServiceState")
                       where rs.Customer.CustomerID == customerId
                       select rs).ToList();
            }
        }

        public IEnumerable<RentalService> GetRentalServicesByState(string state, DateTime fromDate, DateTime toDate)
        {
            using (BigDays2009Entities db = new BigDays2009Entities())
            {
                db.RentalService.MergeOption = MergeOption.NoTracking;

                return (from rs in db.RentalService.Include("Customer").Include("Resource").Include("RentalServiceState")
                       where rs.RentalServiceState.RentalServiceStateName == state
                           && ((fromDate >= rs.StartDate  && fromDate <= rs.EndDate)
                                || (fromDate <= rs.StartDate && toDate >= rs.StartDate))
                       select rs).ToList();
            }
        }

        public IEnumerable<RentalService> GetRentalServicesByResource(int resourceId, DateTime fromDate, DateTime toDate)
        {
            using (BigDays2009Entities db = new BigDays2009Entities())
            {
                db.RentalService.MergeOption = MergeOption.NoTracking;

                return (from rs in db.RentalService.Include("Customer").Include("Resource").Include("RentalServiceState")
                        where rs.Resource.ResourceID == resourceId
                            && ((fromDate >= rs.StartDate && fromDate <= rs.EndDate)
                                || (fromDate <= rs.StartDate && toDate >= rs.StartDate))
                        select rs).ToList();
            }
        }

        public RentalService UpdateRentalService(RentalService updateService)
        {
            using (BigDays2009Entities db = new BigDays2009Entities())
            {
                RentalService originalService = (RentalService)db.GetObjectByKey(updateService.EntityKey);

                db.ApplyPropertyChanges("RentalService", updateService);
                db.ApplyReferencePropertyChanges(updateService, originalService);

                db.SaveChanges();

                return GetRentalService(updateService.RentalServiceID);
            }
        }

        public RentalService CreateRentalService(RentalService newService)
        {
            using (BigDays2009Entities db = new BigDays2009Entities())
            {
                db.RentalService.MergeOption = MergeOption.NoTracking;

                Customer cust = newService.Customer;
                newService.Customer = null;
                newService.CustomerReference.EntityKey = cust.EntityKey;

                RentalServiceState state = newService.RentalServiceState;
                newService.RentalServiceState = null;
                newService.RentalServiceStateReference.EntityKey = state.EntityKey;

                RentResource resource = newService.Resource;
                newService.Resource = null;
                newService.ResourceReference.EntityKey = resource.EntityKey;

                db.AddToRentalService(newService);
                db.SaveChanges();

                return GetRentalService(newService.RentalServiceID);
            }
        }

        public void DeleteRentalService(int rentalServiceId)
        {
            using (BigDays2009Entities db = new BigDays2009Entities())
            {
                db.DeleteObject(db.RentalService.Where(rs => rs.RentalServiceID == rentalServiceId).First());
                db.SaveChanges();
            }
        }

        public IEnumerable<RentalServiceState> GetRentalServiceStates()
        {
            using (BigDays2009Entities db = new BigDays2009Entities())
            {
                db.RentalServiceState.MergeOption = MergeOption.NoTracking;
                return db.RentalServiceState.ToList();
            }
        }
    }
}
